package concurrent;

import java.util.LinkedList;
import java.util.Queue;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author 26029
 * @date 2025/4/28
 * @description
 */
public class LearnLockCondition {
    private static final int MAX_CAPACITY = 5;
    private static final Queue<Integer> queue = new LinkedList<>();

    private static final Lock lock = new ReentrantLock();
    private static final Condition notFull = lock.newCondition();
    private static final Condition notEmpty = lock.newCondition();

    public static void main(String[] args) {
        // 生产者线程
        new Thread(() -> {
            int item = 0;
            while (true) {
                lock.lock();
                try {
                    while (queue.size() == MAX_CAPACITY) {
                        System.out.println("队列满了，生产者等待...");
                        notFull.await();  // 队列满了，生产者等待
                    }
                    queue.offer(item);
                    System.out.println("生产了: " + item);
                    item++;
                    notEmpty.signal();  // 通知消费者可以消费了
                } catch (InterruptedException e) {
                    System.out.println(e.getMessage());
                } finally {
                    lock.unlock();
                }

                try {
                    Thread.sleep(500); // 模拟生产速度
                } catch (InterruptedException e) {
                    System.out.println(e.getMessage());
                }
            }
        }, "Producer").start();

        // 消费者线程
        new Thread(() -> {
            while (true) {
                lock.lock();
                try {
                    while (queue.isEmpty()) {
                        System.out.println("队列空了，消费者等待...");
                        notEmpty.await(); // 队列空了，消费者等待
                    }
                    int item = queue.poll();
                    System.out.println("消费了: " + item);
                    notFull.signal();  // 通知生产者可以继续生产了
                } catch (InterruptedException e) {
                    System.out.println(e.getMessage());
                } finally {
                    lock.unlock();
                }

                try {
                    Thread.sleep(800); // 模拟消费速度
                } catch (InterruptedException e) {
                    System.out.println(e.getMessage());
                }
            }
        }, "Consumer").start();
    }
}
